package ElectricCraft.model;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
* ModelGroup class represents a model groups tree.
*/
public final class ModelGroup {
    public String name;
    public ModelGroup(String name) {
        this.name = name;
    }

    public final List<ModelGroup> groups = new ArrayList<ModelGroup>(4);
    public final List<ChipModel> models = new ArrayList<ChipModel>(4);

    public void save(FileChannel channel, ByteBuffer buffer) throws IOException {
        // name
        byte [] nameBytes = name.getBytes();
        buffer.putInt(nameBytes.length);
        buffer.put(nameBytes);

        // groups count
        buffer.putInt(groups.size());

        // models count
        buffer.putInt(models.size());

        if (buffer.position() > buffer.capacity() / 2) {
            buffer.flip();
            channel.write(buffer);
            buffer.clear();
        }

        // save model groups
        for (ModelGroup gr : groups) {
            gr.save(channel, buffer);
        }

        // save models
        for (ChipModel mdl : models) {
            mdl.save(channel, buffer);
        }
    }

    public void load(int version, InputStream stream, ByteBuffer buffer) throws IOException {
        // name
        int res = stream.read(buffer.array(), 0, 4);
        assert res == 4;

        int nameLength = buffer.getInt(0);
        res = stream.read(buffer.array(), 0, nameLength);
        assert res == nameLength;

        buffer.position(0);
        buffer.limit(nameLength);
        name = Charset.defaultCharset().decode(buffer).toString();

        buffer.clear();
        res = stream.read(buffer.array(), 0, 8);
        assert res == 8;

        // groups & models count
        int groupsCount = buffer.getInt(0);
        int modelsCount = buffer.getInt(4);

        // groups
        groups.clear();
        for (int k = 0; k < groupsCount; ++k) {
            ModelGroup gr = new ModelGroup(null);
            gr.load(version, stream, buffer);
            groups.add(gr);
        }

        // models
        models.clear();
        for (int k = 0; k < modelsCount; ++k) {
            ChipModel mdl = new ChipModel("");
            mdl.load(version, stream, buffer);
            models.add(mdl);
        }
    }

    public ChipModel findModelByName(String name) {
        for (ChipModel model : models) {
            if (model.name.equals(name)) {
                return model;
            }
        }

        return null;
    }

    public ModelGroup findGroupByName(String name) {
        for (ModelGroup group : groups) {
            if (group.name.equals(name)) {
                return group;
            }
        }

        return null;
    }
}
